// Vue3 响应式系统实现
class Dep {
  constructor() {
    this.subscribers = new Set(); // 存放收集的依赖，即副作用函数
  }

  depend() {
    if (activeEffect) {
      this.subscribers.add(activeEffect);
    }
  }

  notify() {
    this.subscribers.forEach((effect) => effect());
  }
}

let activeEffect = null;
function watchEffect(effect) {
  activeEffect = effect;
  effect(); // 收集完依赖后执行该依赖函数
  activeEffect = null;
}
// 创建一个 WeakMap 对象，用于存放所有的依赖
const targetMap = new WeakMap();
// 获取某一个属性对应的依赖 Set 集合
function getDep(target, key) {
  // 根据 target 取出对应的 Map 对象
  let depsMap = targetMap.get(target);
  if (!depsMap) {
    depsMap = new Map();
    targetMap.set(target, depsMap);
  }
  // 取出具体的 dep 对象
  let dep = depsMap.get(key);
  if (!dep) {
    dep = new Dep();
    depsMap.set(key, dep);
  }
  return dep;
}

function reactive(raw) {
  return new Proxy(raw, {
    get(target, key) {
      const dep = getDep(target, key);
      dep.depend();
      return target[key];
    },
    set(target, key, newValue) {
      const dep = getDep(target, key);
      target[key] = newValue;
      dep.notify();
    },
  });
}

const info = reactive({ counter: 100, name: "why" });
console.log("==自动收集依赖==");
watchEffect(() => {
  console.log(info.counter * 2);
});
watchEffect(() => {
  console.log(info.counter * info.counter);
  // console.log(info.counter, info.name);
});
watchEffect(() => {
  console.log(info.name);
});
console.log("=====更新=====");
info.counter++;
info.name = "soso";
